﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YJKInspectModel.ModelValidation.Analyser;
using YJKInspectModel.ModelValidation.Commands;
using YJKInspectModel.ModelValidation.Utils;

namespace YJKInspectModel.ModelValidation.Walls
{
	public partial class UserSelectForm : System.Windows.Forms.Form
	{
		public UserSelectForm(List<ViewPlan> floorInfo, UIDocument uiDoc, List<List<Pole2D>> analyzedPoleListOfProject, List<List<ElementId>> deleteWallIdListOfProject)
		{
			this.m_UIDoc = uiDoc;
			this.m_Doc = this.m_UIDoc.Document;
			this.m_FloorInfo = floorInfo;
			this.m_AnalyzedPoleListOfProject = this.GetAnalyzedPoleListOfProject(analyzedPoleListOfProject);
			this.m_DeleteWallIdListOfProject = deleteWallIdListOfProject;
			this.InitializeComponent();
		}

		public List<List<KeyValuePair<Pole2D, int>>> GetAnalyzedPoleListOfProject(List<List<Pole2D>> analyzedPoleListOfProject)
		{
			List<List<KeyValuePair<Pole2D, int>>> list = new List<List<KeyValuePair<Pole2D, int>>>();
			int num = 0;
			foreach (List<Pole2D> list2 in analyzedPoleListOfProject)
			{
				list.Add(new List<KeyValuePair<Pole2D, int>>());
				foreach (Pole2D wallInfo in list2)
				{
					list[num].AddRange(this.GetWallInfo(wallInfo));
				}
				num++;
			}
			return list;
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		[DllImport("user32.dll")]
		public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

		public void PressEsc()
		{
			int bVk = 27;
			int dwFlags = 0;
			int dwFlags2 = 2;
			int wMsg = 7;
			UserSelectForm.SendMessage(CmdWallsValidation._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			UserSelectForm.keybd_event((byte)bVk, 0, dwFlags, 0);
			UserSelectForm.keybd_event((byte)bVk, 0, dwFlags2, 0);
		}

		public void ResetContinueBreak()
		{
			this.IfBreak = true;
			this.IfManualEsc = true;
			this.IfContinue = false;
		}

		protected override bool ProcessKeyEventArgs(ref Message m)
		{
			int num = 256;
			int num2 = 27;
			if (m.Msg == num && m.WParam.ToInt32() == num2)
			{
				base.Close();
			}
			return base.ProcessKeyEventArgs(ref m);
		}

		public List<List<KeyValuePair<Pole2D, int>>> AnalyzedPoleListOfProject()
		{
			foreach (object obj in this.TreeViewResult.Nodes)
			{
				TreeNode treeNode = (TreeNode)obj;
				int index = Convert.ToInt32(treeNode.Tag.ToString());
				foreach (object obj2 in treeNode.Nodes)
				{
					TreeNode treeNode2 = (TreeNode)obj2;
					if (!treeNode2.Checked)
					{
						int num = Convert.ToInt32(treeNode2.Tag.ToString());
						if (num < this.m_AnalyzedPoleListOfProject[index].Count)
						{
							this.m_AnalyzedPoleListOfProject[index][num] = default(KeyValuePair<Pole2D, int>);
						}
					}
				}
			}
			List<List<KeyValuePair<Pole2D, int>>> list = new List<List<KeyValuePair<Pole2D, int>>>();
			foreach (List<KeyValuePair<Pole2D, int>> list2 in this.m_AnalyzedPoleListOfProject)
			{
				List<KeyValuePair<Pole2D, int>> list3 = new List<KeyValuePair<Pole2D, int>>();
				foreach (KeyValuePair<Pole2D, int> item in list2)
				{
					if (item.Key != null)
					{
						list3.Add(item);
					}
				}
				list.Add(list3);
			}
			return list;
		}

		public List<List<ElementId>> DeleteWallIdListOfProject()
		{
			foreach (object obj in this.TreeViewResult.Nodes)
			{
				TreeNode treeNode = (TreeNode)obj;
				int index = Convert.ToInt32(treeNode.Tag.ToString());
				foreach (object obj2 in treeNode.Nodes)
				{
					TreeNode treeNode2 = (TreeNode)obj2;
					if (!treeNode2.Checked)
					{
						int num = Convert.ToInt32(treeNode2.Tag.ToString());
						if (num < this.m_DeleteWallIdListOfProject[index].Count)
						{
							this.m_DeleteWallIdListOfProject[index][num] = null;
						}
					}
				}
			}
			List<List<ElementId>> list = new List<List<ElementId>>();
			foreach (List<ElementId> list2 in this.m_DeleteWallIdListOfProject)
			{
				List<ElementId> list3 = new List<ElementId>();
				foreach (ElementId elementId in list2)
				{
					if (elementId != null)
					{
						list3.Add(elementId);
					}
				}
				list.Add(list3);
			}
			return list;
		}

		private void UserSelectForm_Load(object sender, EventArgs e)
		{
			//base.Icon = Resource.YArchitechIcon;
			this.ReadData();
			this.InitializeTreeView();
		}

		private void UserSelectForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			this.SaveData();
			this.ClearBoxCurves(true);
			RevitVersionFuncs.ClearSelection(this.m_UIDoc.Selection);
		}

		private void ReadData()
		{
			string path = Path.GetTempPath() + "UserSelectForm.dat";
			if (!File.Exists(path))
			{
				base.StartPosition = FormStartPosition.CenterScreen;
				return;
			}
			base.StartPosition = FormStartPosition.Manual;
			FileStream fileStream = new FileStream(path, FileMode.Open);
			StreamReader streamReader = new StreamReader(fileStream);
			streamReader.BaseStream.Seek(0L, SeekOrigin.Begin);
			int x = Convert.ToInt32(streamReader.ReadLine());
			int y = Convert.ToInt32(streamReader.ReadLine());
			base.Location = new System.Drawing.Point(x, y);
			streamReader.Close();
			fileStream.Close();
		}

		private void SaveData()
		{
			FileStream fileStream = new FileStream(Path.GetTempPath() + "UserSelectForm.dat", FileMode.Create);
			StreamWriter streamWriter = new StreamWriter(fileStream);
			streamWriter.WriteLine(base.Location.X);
			streamWriter.WriteLine(base.Location.Y);
			streamWriter.Flush();
			streamWriter.Close();
			fileStream.Close();
		}

		private void InitializeTreeView()
		{
			for (int i = 0; i < this.m_AnalyzedPoleListOfProject.Count; i++)
			{
				List<KeyValuePair<Pole2D, int>> list = this.m_AnalyzedPoleListOfProject[i];
				List<ElementId> list2 = this.m_DeleteWallIdListOfProject[i];
				TreeNode treeNode = new TreeNode(this.m_FloorInfo[i].Name + "  (" + (list.Count + list2.Count).ToString() + "处待处理)");
				this.TreeViewResult.Nodes.Add(treeNode);
				treeNode.Tag = i;
				treeNode.Checked = true;
				for (int j = 0; j < list.Count; j++)
				{
					TreeNode treeNode2 = new TreeNode("待处理" + (j + 1).ToString());
					treeNode2.Tag = j;
					treeNode2.Checked = true;
					treeNode.Nodes.Add(treeNode2);
				}
				for (int j = 0; j < list2.Count; j++)
				{
					TreeNode treeNode3 = new TreeNode("待处理" + (j + list.Count + 1).ToString());
					treeNode3.Tag = j + list.Count;
					treeNode3.Checked = true;
					treeNode.Nodes.Add(treeNode3);
				}
				treeNode.Expand();
			}
		}

		public void RefreshTree(List<List<KeyValuePair<Pole2D, int>>> analyzedPoleListOfProject, List<List<ElementId>> deleteWallIdListOfProject)
		{
			this.TreeViewResult.Nodes.Clear();
			this.m_AnalyzedPoleListOfProject = analyzedPoleListOfProject;
			this.m_DeleteWallIdListOfProject = deleteWallIdListOfProject;
			this.InitializeTreeView();
		}

		private void ZoomToElement(List<ElementId> ids, List<List<KeyValuePair<XYZ, XYZ>>> positionBoxListList)
		{
			this.m_UIDoc.ShowElements(ids);
			List<Element> list = new List<Element>();
			foreach (ElementId elementId in ids)
			{
				list.Add(this.m_UIDoc.Document.GetElement(elementId));
			}
			RevitVersionFuncs.SetSelection(this.m_UIDoc.Selection, list);
			this.m_UIDoc.RefreshActiveView();
			if (positionBoxListList.Count > 0)
			{
				using (List<List<KeyValuePair<XYZ, XYZ>>>.Enumerator enumerator2 = positionBoxListList.GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						List<KeyValuePair<XYZ, XYZ>> boxList = enumerator2.Current;
						this.DrawBoxs(boxList);
					}
					return;
				}
			}
			this.ClearBoxCurves(true);
		}

		private object GetItemByIndex(int indexFloor, int index, ref List<KeyValuePair<XYZ, XYZ>> positionBoxList)
		{
			double num = Common.MMToFeet(500.0);
			object result;
			if (index >= this.m_AnalyzedPoleListOfProject[indexFloor].Count)
			{
				index -= this.m_AnalyzedPoleListOfProject[indexFloor].Count;
				ElementId elementId = this.m_DeleteWallIdListOfProject[indexFloor][index];
				Curve curve = ((this.m_Doc.GetElement(elementId) as Wall).Location as LocationCurve).Curve;
				XYZ endPoint = curve.GetEndPoint(0);
				XYZ endPoint2 = curve.GetEndPoint(1);
				double num2 = Geometry.LessThan(endPoint.X, endPoint2.X) ? endPoint.X : endPoint2.X;
				double num3 = Geometry.GreaterThan(endPoint.X, endPoint2.X) ? endPoint.X : endPoint2.X;
				double num4 = Geometry.LessThan(endPoint.Y, endPoint2.Y) ? endPoint.Y : endPoint2.Y;
				double num5 = Geometry.GreaterThan(endPoint.Y, endPoint2.Y) ? endPoint.Y : endPoint2.Y;
				XYZ key = new XYZ(num2 - num, num4 - num, 0.0);
				XYZ value = new XYZ(num3 + num, num5 + num, 0.0);
				positionBoxList.Add(new KeyValuePair<XYZ, XYZ>(key, value));
				result = elementId;
			}
			else
			{
				Pole2D key2 = this.m_AnalyzedPoleListOfProject[indexFloor][index].Key;
				ElementId componentId = key2.ComponentId;
				Curve curve2 = ((this.m_Doc.GetElement(componentId) as Wall).Location as LocationCurve).Curve;
				XYZ endPoint3 = curve2.GetEndPoint(0);
				XYZ endPoint4 = curve2.GetEndPoint(1);
				XYZ key3;
				XYZ value2;
				if (this.m_AnalyzedPoleListOfProject[indexFloor][index].Value == 0)
				{
					key3 = new XYZ(endPoint3.X - num, endPoint3.Y - num, 0.0);
					value2 = new XYZ(endPoint3.X + num, endPoint3.Y + num, 0.0);
				}
				else
				{
					key3 = new XYZ(endPoint4.X - num, endPoint4.Y - num, 0.0);
					value2 = new XYZ(endPoint4.X + num, endPoint4.Y + num, 0.0);
				}
				positionBoxList.Add(new KeyValuePair<XYZ, XYZ>(key3, value2));
				result = key2;
			}
			return result;
		}

		private List<KeyValuePair<Pole2D, int>> GetWallInfo(Pole2D wallInfo)
		{
			List<KeyValuePair<Pole2D, int>> list = new List<KeyValuePair<Pole2D, int>>();
			ElementId componentId = wallInfo.ComponentId;
			Curve curve = ((this.m_Doc.GetElement(componentId) as Wall).Location as LocationCurve).Curve;
			XYZ endPoint = curve.GetEndPoint(0);
			XYZ endPoint2 = curve.GetEndPoint(1);
			if (!Geometry.IsEqual(new XYZ(endPoint.X, endPoint.Y, wallInfo.StartPoint.Z), wallInfo.StartPoint))
			{
				list.Add(new KeyValuePair<Pole2D, int>(wallInfo, 0));
			}
			if (!Geometry.IsEqual(new XYZ(endPoint2.X, endPoint2.Y, wallInfo.EndPoint.Z), wallInfo.EndPoint))
			{
				list.Add(new KeyValuePair<Pole2D, int>(wallInfo, 1));
			}
			return list;
		}

		private void TreeViewResult_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
		{
			if (e.Node == null)
			{
				return;
			}
			if (e.Node.Nodes.Count > 0)
			{
				try
				{
					int num = Convert.ToInt32(e.Node.Tag.ToString());
					if (this.m_UIDoc.ActiveView.Id.IntegerValue != this.m_FloorInfo[num].Id.IntegerValue)
					{
						this.m_UIDoc.ActiveView = this.m_FloorInfo[num];
					}
					int num2 = this.m_AnalyzedPoleListOfProject[num].Count + this.m_DeleteWallIdListOfProject[num].Count;
					List<ElementId> list = new List<ElementId>();
					for (int i = 0; i < num2; i++)
					{
						List<KeyValuePair<XYZ, XYZ>> list2 = new List<KeyValuePair<XYZ, XYZ>>();
						object itemByIndex = this.GetItemByIndex(num, i, ref list2);
						if (itemByIndex.GetType() == typeof(Pole2D))
						{
							Pole2D pole2D = itemByIndex as Pole2D;
							list.Add(pole2D.ComponentId);
						}
						else
						{
							ElementId item = itemByIndex as ElementId;
							list.Add(item);
						}
					}
					this.ZoomToElement(list, new List<List<KeyValuePair<XYZ, XYZ>>>());
					return;
				}
				catch (Exception)
				{
					return;
				}
			}
			try
			{
				int num3 = Convert.ToInt32(e.Node.Parent.Tag.ToString());
				if (this.m_UIDoc.ActiveView.Id.IntegerValue != this.m_FloorInfo[num3].Id.IntegerValue)
				{
					this.m_UIDoc.ActiveView = this.m_FloorInfo[num3];
				}
				int index = Convert.ToInt32(e.Node.Tag.ToString());
				List<KeyValuePair<XYZ, XYZ>> item2 = new List<KeyValuePair<XYZ, XYZ>>();
				object itemByIndex2 = this.GetItemByIndex(num3, index, ref item2);
				List<List<KeyValuePair<XYZ, XYZ>>> list3 = new List<List<KeyValuePair<XYZ, XYZ>>>();
				list3.Add(item2);
				List<ElementId> list4 = new List<ElementId>();
				if (itemByIndex2.GetType() == typeof(Pole2D))
				{
					Pole2D pole2D2 = itemByIndex2 as Pole2D;
					list4.Add(pole2D2.ComponentId);
				}
				else
				{
					ElementId item3 = itemByIndex2 as ElementId;
					list4.Add(item3);
				}
				this.ZoomToElement(list4, list3);
			}
			catch (Exception)
			{
			}
		}

		private void SetParentChecked(TreeNode childNode)
		{
			TreeNode parent = childNode.Parent;
			if (!parent.Checked && childNode.Checked)
			{
				int num = 0;
				for (int i = 0; i < parent.GetNodeCount(false); i++)
				{
					if (parent.Nodes[i].Checked)
					{
						num++;
					}
				}
				if (num == parent.GetNodeCount(false))
				{
					this.m_RefreshChildNodeCheck = false;
					parent.Checked = true;
					if (parent.Parent != null)
					{
						this.SetParentChecked(parent);
						return;
					}
				}
			}
			else if (parent.Checked && !childNode.Checked)
			{
				this.m_RefreshChildNodeCheck = false;
				parent.Checked = false;
			}
		}

		private void SetChildChecked(TreeNode parentNode)
		{
			if (!this.m_RefreshChildNodeCheck)
			{
				this.m_RefreshChildNodeCheck = true;
				return;
			}
			for (int i = 0; i < parentNode.GetNodeCount(false); i++)
			{
				TreeNode treeNode = parentNode.Nodes[i];
				treeNode.Checked = parentNode.Checked;
				if (treeNode.GetNodeCount(false) > 0)
				{
					this.SetChildChecked(treeNode);
				}
			}
		}

		private void TreeViewResult_AfterCheck(object sender, TreeViewEventArgs e)
		{
			this.SetChildChecked(e.Node);
			if (e.Node.Parent != null)
			{
				this.SetParentChecked(e.Node);
			}
		}

		private void ClearBoxCurves(bool includeTranssaction)
		{
			Transaction transaction = null;
			try
			{
				if (includeTranssaction)
				{
					transaction = new Transaction(this.m_Doc);
					transaction.Start("delete box curves");
				}
				if (this.m_BoxCurvesId.Count > 0)
				{
					this.m_Doc.Delete(this.m_BoxCurvesId);
					this.m_BoxCurvesId.Clear();
				}
				if (includeTranssaction)
				{
					transaction.Commit();
				}
			}
			catch (Exception)
			{
				if (includeTranssaction && transaction.IsValidObject && transaction.HasStarted())
				{
					transaction.RollBack();
				}
				this.m_BoxCurvesId.Clear();
				this.PressEsc();
			}
		}

		private void DrawBoxs(List<KeyValuePair<XYZ, XYZ>> boxList)
		{
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(this.m_Doc);
				transaction.Start("draw box");
				if (this.m_BoxCurvesId.Count > 0)
				{
					this.m_Doc.Delete(this.m_BoxCurvesId);
					this.m_BoxCurvesId.Clear();
				}
				this.ClearBoxCurves(false);
				CurveArray curveArray = new CurveArray();
				foreach (KeyValuePair<XYZ, XYZ> keyValuePair in boxList)
				{
					XYZ xyz = new XYZ(keyValuePair.Value.X, keyValuePair.Key.Y, 0.0);
					XYZ xyz2 = new XYZ(keyValuePair.Key.X, keyValuePair.Value.Y, 0.0);
					curveArray.Append(Line.CreateBound(keyValuePair.Key, xyz));
					curveArray.Append(Line.CreateBound(xyz, keyValuePair.Value));
					curveArray.Append(Line.CreateBound(keyValuePair.Value, xyz2));
					curveArray.Append(Line.CreateBound(xyz2, keyValuePair.Key));
				}
				DetailCurveArray detailCurveArray = this.m_Doc.Create.NewDetailCurveArray(this.m_Doc.ActiveView, curveArray);
				if (this.GetLineStyle())
				{
					foreach (object obj in detailCurveArray)
					{
						DetailCurve detailCurve = (DetailCurve)obj;
						detailCurve.LineStyle = this.m_LineStyle;
						this.m_BoxCurvesId.Add(detailCurve.Id);
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction != null)
				{
					transaction.RollBack();
				}
			}
		}

		private bool GetLineStyle()
		{
			if (this.m_LineStyle != null)
			{
				return true;
			}
			Category category = this.m_Doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category == null)
			{
				return false;
			}
			int num = 6;
            Autodesk.Revit.DB.Color lineColor = new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0);
			if (!category.SubCategories.Contains(this.m_StrLineName))
			{
				if (!this.CreateLineStyle(num, this.m_StrLineName, lineColor, ref category))
				{
					return false;
				}
			}
			else
			{
				Category category2 = category.SubCategories.get_Item(this.m_StrLineName);
				category2.LineColor = lineColor;
				category2.SetLineWeight(num, (Autodesk.Revit.DB.GraphicsStyleType)1);
			}
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null && graphicsStyle.Name.CompareTo(this.m_StrLineName) == 0)
				{
					this.m_LineStyle = graphicsStyle;
				}
			}
			return this.m_LineStyle != null;
		}

        private bool CreateLineStyle(int lineWidth, string typeName, Autodesk.Revit.DB.Color lineColor, ref Category lineCategory)
		{
			bool result;
			try
			{
				Category category = this.m_Doc.Settings.Categories.NewSubcategory(lineCategory, typeName);
				category.LineColor = lineColor;
				category.SetLineWeight(lineWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private void CloseCancel_Click(object sender, EventArgs e)
		{
			base.Close();
		}

		private void HandleBtn_Click(object sender, EventArgs e)
		{
			this.IfContinue = true;
			if (this.m_AnalyzedPoleListOfProject.Count > 0)
			{
				RevitVersionFuncs.ClearSelection(this.m_UIDoc.Selection);
			}
			this.PressEsc();
		}

		private UIDocument m_UIDoc;

		private Document m_Doc;

		private List<List<KeyValuePair<Pole2D, int>>> m_AnalyzedPoleListOfProject;

		private List<List<ElementId>> m_DeleteWallIdListOfProject;

		private List<ViewPlan> m_FloorInfo;

		private GraphicsStyle m_LineStyle;

		public string m_StrLineName = "HYPositionBox";

		private List<ElementId> m_BoxCurvesId = new List<ElementId>();

		private bool m_RefreshChildNodeCheck = true;
	}
}
